package pomodorotasks

import com.google.api.client.auth.oauth2.draft10.AccessTokenResponse;
import com.google.api.client.googleapis.auth.oauth2.draft10.GoogleAccessProtectedResource;
import com.google.api.client.googleapis.auth.oauth2.draft10.GoogleAccessTokenRequest.GoogleAuthorizationCodeGrant;
import com.google.api.client.googleapis.auth.oauth2.draft10.GoogleAuthorizationRequestUrl;
import com.google.api.client.http.ByteArrayContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.google.api.services.tasks.model.Tasks
import com.google.api.services.tasks.model.TaskList
import com.google.api.services.tasks.model.TaskLists
import com.google.api.services.tasks.model.Task

import org.apache.commons.beanutils.BeanUtils

class GoogleTasksService {
    
    String SCOPE = "https://www.googleapis.com/auth/tasks"
    String CALLBACK_URL = "urn:ietf:wg:oauth:2.0:oob"
    HttpTransport TRANSPORT = new NetHttpTransport()
    JsonFactory JSON_FACTORY = new JacksonFactory()

    String CLIENT_ID = "249750969063.apps.googleusercontent.com"
    String CLIENT_SECRET = "eCCToA1bw56p8mb4pekGMbcN"
    
    com.google.api.services.tasks.Tasks service
    
    TaskLists taskLists
    
    def controller
    
    String TASK_STATUS_COMPLETED = 'completed'
    
    def initConnection(_controller) {
        controller = _controller
        // Generate the URL to which we will direct users
        String authorizeUrl = new GoogleAuthorizationRequestUrl(CLIENT_ID,
            CALLBACK_URL, SCOPE).build();

        // Wait for the authorization code
        controller.getAuthorizationCode(authorizeUrl, makeConnection)
        
    }
    
    def makeConnection = { authorizationCode ->
        println "Read:${authorizationCode}"

        // Exchange for an access and refresh token
        GoogleAuthorizationCodeGrant authRequest = new GoogleAuthorizationCodeGrant(TRANSPORT,
            JSON_FACTORY, CLIENT_ID, CLIENT_SECRET, authorizationCode, CALLBACK_URL);
        println 'a'
        AccessTokenResponse authResponse = authRequest.execute();
        String accessToken = authResponse['access_token']
        String refresh_token = authResponse['refresh_token']
        GoogleAccessProtectedResource access = new GoogleAccessProtectedResource(accessToken,
            TRANSPORT, JSON_FACTORY, CLIENT_ID, CLIENT_SECRET, refresh_token);
      
        println 'c'
        service = new com.google.api.services.tasks.Tasks(TRANSPORT, access, JSON_FACTORY)
        service.setApplicationName("PomodoroTasks")
        println 'd'
        
        updateData()
    }
    
    TaskLists getTaskLists() {
        return service.tasklists.list().execute();
    }
    
    void updateData() {
        controller.updateTaskList(getTaskLists())
    }
    
    Tasks getTasks(TaskList list) {
        log.debug("Retrieving tasks for list: $list.title")
        return service.tasks.list(list.id).execute()
    }
    
    void updateTask(TaskList list, Task task) {
        log.debug("Updating task: $task.id : $task.title")
        if (task.status != TASK_STATUS_COMPLETED) {
            task.completed = null
        }
        Task result = service.tasks.update(list.id, task.id, task).execute();
        BeanUtils.copyProperties(task, result)
        log.debug("Updated task $task.id ")
    }
    
    Task addTask(TaskList list) {
        log.debug("Adding new task to list: $list.title")
        Task task = new Task();
        Task result = service.tasks.insert(list.id, task).execute();
        log.debug("Added new task to list: $list.title")
        return result
    }
}